package board.command;

import java.awt.*;
import java.util.*;

import board.Board;

import sgf.SGFParseException;
import sgf.SGFUtils;

/**
 * Adds stones to the board.  This is for setup stones, not actual moves.
 * @author TKington
 *
 */
public class AddCommand extends Command {
	/** The color of stones being added - 1 for black, -1 for white. */
    private int player;
    /** The x,y locations where stones are being added. */
    private ArrayList<Point> points;
    
    /**
     * Creates a new AddCommand object.
     * @param player 1 for black, -1 for white
     * @param props the list of properties from the SGF AW or AB tag
     * @throws SGFParseException if the properties are illegal
     */
    public AddCommand(int player, ArrayList props) throws SGFParseException {
        this.player = player;
        points = new ArrayList<Point>();
        for(int i = 0; i < props.size(); i++) {
            points.addAll(SGFUtils.stringToPoints((String)props.get(i)));
        }
    }
    
    /**
     * Creates an empty AddCommand object
     * @param player 1 for black, -1 for white
     */
    public AddCommand(int player) {
        this.player = player;
    }
    
    /**
     * Sets the list of Points where stones should be added.
     * @param pts the list of Points
     */
    public void setPoints(ArrayList<Point> pts) { points = pts; }
    
    @Override
	public boolean doIt(Board b) {
        for(int i = 0; i < points.size(); i++) {
            Point pt = points.get(i);
            b.setAt(pt.x, pt.y, player);
        }
        return true;
    }
    
    @Override
	public void undoIt(Board b) {
        for(int i = 0; i < points.size(); i++) {
            Point pt = points.get(i);
            b.remove(pt.x, pt.y);
        }
    }
    
    @Override
	public Rectangle getBounds() {
        Rectangle ret = null;
        for(int i = 0; i < points.size(); i++) {
            Point p = points.get(i);
            if(ret == null)
                ret = new Rectangle(p);
            else ret.add(p);
        }
        return ret;
    }
    
    @Override
	public void validatePoints(int size) throws SGFParseException {
        for(int i = 0; i < points.size(); i++) {
            Point p = points.get(i);
            SGFUtils.checkPoint(p, size);
        }
    }
    
    /**
     * Adds a Point to the AddCommand.
     * @param p the Point
     */
    public void addPoint(Point p) {
    	if(points == null)
    		points = new ArrayList<Point>();
    	points.add(p);
    }
    
    /**
     * Removes a Point from the AddCommand.
     * @param p the Point
     */
    public void removePoint(Point p) {
    	for(int i = 0; i < points.size(); i++) {
    		Point p2 = points.get(i);
    		if(p.equals(p2)) {
    			points.remove(i);
    			i--;
    		}
    	}
    }
    
    /**
     * Removes a Point from the AddCommand.
     * @param x the x location
     * @param y the y location
     * @return true if the Point was found and removed
     */
    public boolean removePoint(int x, int y) {
    	boolean found = false;
    	for(int i = 0; i < points.size(); i++) {
    		Point p = points.get(i);
    		if(p.x == x && p.y == y) {
    			points.remove(i);
    			i--;
    			found = true;
    		}
    	}
    	
    	return found;
    }
    
    /**
     * Checks to see if a given point is contained in this AddCommand.
     * @param x the x location
     * @param y the y location
     * @return true if the Point is found
     */
    public boolean hasPoint(int x, int y) {
    	for (Iterator iter = points.iterator(); iter.hasNext();) {
			Point p = (Point) iter.next();
			if(p.x == x && p.y == y)
				return true;
		}
    	
    	return false;
    }
    
    /**
     * Returns the color of stones added by this AddCommand.
     * @return 1 for black, -1 for white
     */
    public int getPlayer() { return player; }
}
